const config = require('./config');
const utils = require("../../common/utils");
const constant = require('../../common/mj_constant');
const GameBase = require("./game_base");
const mjutils = require('./mjutils');
const db = require("../../common/db");
const mjhu = require('./hu.js');

class HENMJGame extends GameBase {

    constructor(roomId) {
        super(roomId);
        //this._game = global.Games.rooms[roomId];
        this._zhuang = 0;
        // this._gameCount = 0;
        // this._roomId = roomId;

        this._cards = [];
        this._handCards = [];
        this._handCardsMap = [];
        this._lastCard = -1;
        this._lastChair = -1;
        this._combo = {};
        this._turn = 0;
        this._actions = [];
        this._actionCache = {};
        this._userActions = {};
        this._tingMap = {};
        // this._pao = null;
        // this._magic = 31;
        this._magic = 33;
        this._zimoCard = -1;
        this._tongji = [];
        this._mopai = -1;
        this._record = {};
        this._lastChiMan = -1;
        this._lastChiBan = [];
        this._pos = [];
        this._huBan = [];
        // this._lastNotifyTime = new Date().getTime();
        this._autoDismissTimer = null;


        for (var i = 0; i < 4; i++) {
            this._tongji.push({
                zimo: 0,
                jiepao: 0,
                angang: 0,
                dianpao: 0,
                minggang: 0
            })
        }
    }


    /**
     * 预设游戏规则
     *
     * feng : 带风牌 true/false
     * hongzhong : 红中玩法 true/false
     * hu : 普通平胡，只炸不胡 0/1
     * jiang258 : 只能用258做将 true/false
     * hu258fan : 胡258加番 true/false
     * jiang258fan : 将258加番 true/false
     * 7duifan : 不许胡，可胡7对（加番），不加番 0/1/2
     * qingyise : 清一色加番 true/false
     *
     */



    start() {
        super.start();
        this.startAutoDismissTimer();

        if (!this._roomInfo.gameConfig.hongzhong) {
            this._magic = -100;
        } else {
            this._magic = 33;
            // this._magic = this._magic;
        }
        
        // this._gameCount++;
        this._game = global.Games.rooms[this._roomId];
        this._fan = 0;

        //庄家随机
        //第一轮需要初始化的数据
        if (this._gameCount == 1 || this._lastWinner == -1) {
            //this._zhuang = utils.rand(0,this._game.players.length - 1);
            this._zhuang = 0;
            //for(var i = 0; i < this._game.players.length; i++){
            //    this._gameScore[i] = 0;
            //}
        } else {
            this._zhuang = this._lastWinner;
        }


        //this.sendToRoom("game_start_push");
        this._turn = this._zhuang;
        this._cards = [];
        this._lastCard = -1;
        this._lastChair = -1;
        this._lastWinner = -1;
        this._zimoCard = -1;
        this._lastChiMan = -1;
        this._lastChiBan = [];
        this._combo = {};
        this._actions = {};
        this._userActions = {};
        this._actionCache = {
            peng: [],
            gang: [],
            hu: []
        }
        this._outCards = {};
        this._showAllCards = 0;
        this._scoreChanged = {}
        this._hua = [];
        this._huBan = [];
        for (var i = 0; i < this._game.players.length; i++) {
            //this._actions.push(constant.ACTION_NULL);
            // this._userActions[i] = constant.ACTION_NULL;
            this._combo[i] = [];
            this._hua[i] = [];
            this._handCardsMap[i] = {};
            this._handCards[i] = [];
            this._outCards[i] = [];
            this._tingMap[i] = {};
            this._huBan[i] = [];

            for (var j = 0; j < 34; j++) {
                this._handCardsMap[i][j] = 0;
            }
            this._scoreChanged[i] = 0;
        }

        //统计点杠和暗杠以及明杠
        this._xjtongji = [];
        for (var i = 0; i < 4; i++) {
            this._xjtongji.push({
                diangang: 0,
                minggang: 0,
                angang: 0
            });
        }

        //风位
        if (this._game.players.length == 2) {
            for (let i = 0; i < 2; i++) {
                this._pos[i] = (this._zhuang === i) ? 27 : 29;
            }
        } else {
            this._pos = [27, 28, 29, 30];
            for (let i = 0; i < this._zhuang; i++) {
                this._pos.unshift(this._pos.pop());
            }
        }

        //洗牌
        this.xipai();

        this._state = 'game';

        //@yang
        //给所有用户发牌
        for (var j = 0; j < this._game.players.length; j++) {
            for (var i = 0; i < config.DEFAULT_HAND_CARDS; i++) {
                this.mopai(j, false, false);
            }
            //this.updateTing(j);
        }

        this.sendToRoom("game_start_push");
        this.pushState();
        this.pushGameInfo();

        this.prepareRecord();

        this._turn = this._zhuang;
        this.pushHolds();
        this.record("holds_push", JSON.parse(JSON.stringify(this._handCards)));
        this.pushTurn();
        this.record("turn_push", {
            turn: this._turn
        });


        this.mopai(this._turn, true, true);

        //下炮子
        // this._pao = {};
        // this._turn = -1;

        // this.pushTurn();
        //this.record("turn_push",{turn : this._turn});

        // this.pushPao();
        // this.sync();
        // this.notifyChupai();
    }

    /**
     * 推送手牌
     * @param chairID
     */
    pushHolds(chairId = -1) {
        if (chairId == -1) {
            return this._userInfo.forEach(function (u, chairId) {
                if (u === null) return;
                this.pushHolds(chairId)
            }.bind(this));
        }
        var data = [];
        for (var i = 0; i < this._handCards.length; i++) {
            if (i == chairId) {
                data.push(this._handCards[i])
            } else {
                data.push(this._handCards[i].length);
            }
        }
        this.sendToChair(chairId, "holds_push", data);
    }

    /**
     * 推送已经出过的牌
     * @param chairId
     * @param undefined
     */
    pushOut(chairId = -1) {
        if (chairId == -1) {
            return this._userInfo.forEach(function (u, chairId) {
                if (u === null) return;
                this.pushOut(chairId)
            }.bind(this));
        }
        this.sendToChair(chairId, "out_cards_push", this._outCards);
    }

    pushGameInfo(chairId = -1) {
        if (chairId == -1) {
            return this._userInfo.forEach(function (u, chairId) {
                if (u === null) return;
                this.pushGameInfo(chairId)
            }.bind(this));
        }
        this.sendToChair(chairId, "game_info_push", {
            gameCount: this._gameCount,
            state: this._state,
            zhuang: this._zhuang,
            gameScore: this._gameScore,
            leftCardCount: this._cards.length,
            dismiss: this._dismissApply,
            roomInfo: this._roomInfo,
            pos: this._pos,
            lastCard : this._lastCard,
            lastChair : this._lastChair
        });
    }

    pushTurn(chairId = -1) {
        if (chairId == -1) {
            return this._userInfo.forEach(function (u, chairId) {
                if (u === null) return;
                this.pushTurn(chairId)
            }.bind(this));
        }
        //清空我自己的huban
        this._huBan[chairId] = [];
        this.sendToChair(chairId, "turn_push", {
            turn: this._turn
        });
    }

    // pushPao(chairId = -1) {
    //     if (chairId == -1) {
    //         return this._userInfo.forEach(function (u, chairId) {
    //             if (u === null) return;
    //             this.pushPao(chairId)
    //         }.bind(this));
    //     }
    //     this.sendToChair(chairId, "pao_push", this._pao);
    // }

    pushCombo(chairId = -1) {
        if (chairId == -1) {
            return this._userInfo.forEach(function (u, chairId) {
                if (u === null) return;
                this.pushCombo(chairId)
            }.bind(this));
        }
        this.sendToChair(chairId, "combo_push", this._combo);
    }

    pushActions(chairId = -1) {
        if (chairId == -1) {
            return this._userInfo.forEach(function (u, chairId) {
                if (u === null) return;
                this.pushActions(chairId)
            }.bind(this));
        }
        if (Object.keys(this._actions).length) {
            this.sendToChair(chairId, "action_push", this._actions);
        }
    }

    pushHua(chairId = -1) {
        if (chairId === -1) {
            return this._userInfo.forEach((u, c) => {
                if (u === null) return;
                this.pushHua(c);
            });
        }
        this.sendToChair(chairId, 'hua_push', this._hua);
    }

    // pushLastChupai(chairId,undefined){
    //
    // }


    sync(chairId = -1) {
        this.pushState(chairId);
        this.pushUsers(chairId);
        this.pushGameInfo(chairId);


        //chairId = undefined;
        var self = this;
        //super.sync(chairId);
        if (this._state == 'game') {

            this.pushCombo(chairId);
            this.pushHolds(chairId);
            this.pushTurn(chairId);
            this.pushOut(chairId);
            this.pushActions(chairId);
            this.pushHua(chairId);
            // this.pushPao(chairId);
        }

    }

    startAutoDismissTimer(){
        if(this._autoDismissTimer){
            clearTimeout(this._autoDismissTimer);
            this._autoDismissTimer = null;
        }
        this._autoDismissTimer = setTimeout(() => {
            this.sendToRoom("auto_dismiss_push");
            this.sendToRoom("zongjie_push", {
                gameScore: this._gameScore,
                tongji: this._tongji,
                allScoreInfo: this._eachTurnScore
            });
            this.forceDismissRoom();
        },300000);
    }

    onMessage(chairId, event, data) {
       
        this.startAutoDismissTimer();
        // let now = new Date().getTime();

        var self = this;
        switch (event) {
            case 'chupai_pull':
                if (chairId != this._turn) return false;
                var card = Number(data.card);
                if (this._handCardsMap[chairId][card] == 0) return false;

                //
                if (this._lastChair === chairId) {
                    if (this._lastChiBan.includes(card)) {
                        return false;
                    }
                }

                this._lastChiMan = -1;
                this._lastChiBan = [];

                //删除出牌
                var index = this._handCards[chairId].indexOf(card);
                if (index > -1) {
                    this._handCards[chairId].splice(index, 1);
                }
                this._handCardsMap[chairId][card]--;
                this._lastCard = card;
                this._lastChair = chairId;
                this._outCards[chairId].push(card);
                //更新听牌
                // this._game.players.forEach(function (player, index) {
                // self.updateTing(index);
                // });

                this.sendToRoom("chupai_push", {
                    chairId: chairId,
                    card: card
                });
                this.record("chupai_push", {
                    chairId: chairId,
                    card: card
                });
                //self.updateTing(i);

                this._actions = {};
                this._actionCache = {
                    peng: [],
                    gang: [],
                    hu: []
                };
                this._userActions = {};


                do {
                    //允许打出万能牌，但是打出的万能牌不做任何运算
                    if (card == this.magic) {
                        break;
                    }

                    //检查动作
                    for (var i = 0; i < this._game.players.length; i++) {
                        if (i == chairId) {
                            continue;
                        }
                        var action = {
                            peng: 0,
                            gang: 0,
                            hu: 0,
                            diangang: 0,
                            angang: 0,
                            penggang: 0
                        };
                        if (self.checkPeng(i, card)) {
                            action.peng = 1;
                        }
                        if (self.checkDianGang(i, card) !== false) {
                            action.gang = 1;
                            //action.diangang = 1;
                            //this._actionCache[i].diangang.push(card);
                        }
                        if (self.checkHu(i, card, true)) {
                            action.hu = 1;
                        }
                        // if(self.checkGang(i,card)){
                        // }
                        // if(self.updateTing(i,card)){
                        //     action.hu = 1;
                        // }

                        if (this.getNextPlayer(chairId) == i) {
                            let chi = this.checkChi(i, card);
                            if (chi) {
                                let ret = chi.filter(item => !item.includes(this._magic));
                                action.chi = ret;
                            }
                        }


                        if (!action.hu &&
                            !action.peng &&
                            !action.gang &&
                            (!action.chi || !action.chi.length)) {
                            continue;
                        }
                        this._actions[i] = action;
                    }
                } while (0);

                //等待执行动作
                if (Object.keys(this._actions).length) {
                    this._turn = -1;
                    this.pushTurn();
                    this.pushActions();

                    this.record("turn_push", {
                        turn: this._turn
                    });
                    // this.sendToRoom("chupai_success_push",{
                    //     chairId:chairId,
                    //     card : card,
                    //     actions : this._actions,
                    //     turn : -1
                    // });
                } else {
                    this.moveToNextPlayer();
                    this.mopai(this._turn, true, true);
                }
                //this.sync();
                break;
            case 'peng_pull':
                //不是你碰，你碰什么呢
                if (!this._actions[chairId]) {
                    return;
                }
                if (!this._actions[chairId].peng) {
                    return;
                }
                if (!this.checkPeng(chairId, this._lastCard)) {
                    return;
                }

                //一炮多响的情况下，点过等于点胡
                // if (this._actions[chairId].hu) {
                //     let canHuCount = (() => {
                //         let flag = false;
                //         for (const cid in this._actions) {
                //             if (cid != chairId && this._actions[cid] && this._actions[cid].hu) {
                //                 flag = true;
                //             }
                //         }
                //         return flag;
                //     })();
                //     let doHuCount = this._actionCache.hu.length;
                //     if (canHuCount || doHuCount) {
                //         return this.onMessage(chairId, "hu_pull");
                //     }

                // }
                this._actionCache.peng.push(chairId);
                this._actions[chairId] = null;

                //检查是否需要等待
                for (var i in this._actions) {
                    if (!this._actions[i]) continue;

                    if (this._actions[i].peng || this._actions[i].gang || this._actions[i].hu) {
                        return;
                    }
                }
                this.doAction();
                break;
            case 'gang_pull':
                //不是你碰，你碰什么呢
                if (!this._actions[chairId] || !this._actions[chairId].gang) {
                    return;
                }

                //一炮多响的情况下，点过等于点胡
                // if (this._actions[chairId].hu) {
                //     let canHuCount = (() => {
                //         let flag = false;
                //         for (const cid in this._actions) {
                //             if (cid != chairId && this._actions[cid] && this._actions[cid].hu) {
                //                 flag = true;
                //             }
                //         }
                //         return flag;
                //     })();
                //     let doHuCount = this._actionCache.hu.length;
                //     if (canHuCount || doHuCount) {
                //         return this.onMessage(chairId, "hu_pull");
                //     }

                // }

                this._actionCache.gang.push(chairId);
                this._actions[chairId] = null;

                for (var i in this._actions) {
                    if (!this._actions[i]) continue;
                    if (this._actions[i].gang || this._actions[i].hu) {
                        return;
                    }
                }


                this.doAction();
                break;
            case 'hu_pull':
                if (!this._actions[chairId] || !this._actions[chairId].hu) {
                    return;
                }
                // if(!this.checkGang(chairId,this._lastCard)){
                //     return;
                // }
                //删除自己的行为
                this._actionCache.hu.push(chairId);
                this._actions[chairId] = null;
                //检查是否需要等待
                for (var i in this._actions) {
                    if (!this._actions[i]) continue;
                    if (this._actions[i].hu) {
                        return;
                    }
                }
                this.doAction();
                break;

                /**
                 * 吃牌
                 */
            case 'chi_pull':
                if (!this._actions[chairId] ||
                    !this._actions[chairId].chi ||
                    !this._actions[chairId].chi.length
                ) {
                    return;
                }

                //一炮多响的情况下，点过等于点胡
                // if (this._actions[chairId].hu) {
                //     let canHuCount = (() => {
                //         let flag = false;
                //         for (const cid in this._actions) {
                //             if (cid != chairId && this._actions[cid] && this._actions[cid].hu) {
                //                 flag = true;
                //             }
                //         }
                //         return flag;
                //     })();
                //     let doHuCount = this._actionCache.hu.length;
                //     if (canHuCount || doHuCount) {
                //         return this.onMessage(chairId, "hu_pull");
                //     }

                // }

                let card1 = data.cards[0],
                    card2 = data.cards[1];
                // let matched = false;
                let matched = this._actions[chairId].chi.filter(item => {
                    return item.includes(card1) && item.includes(card2);
                });
                if (!matched.length) {
                    return;
                }
                this._actionCache.chi = this._actionCache.chi || [];
                this._actionCache.chi.push([chairId, matched[0]]);
                this._actions[chairId] = null;
                for (let ch in this._actions) {
                    const action = this._actions[ch];
                    if (!action) {
                        continue;
                    }
                    if (action.peng || action.gang || action.hu) {
                        return;
                    }
                }
                this.doAction();
                break;

            case 'guo_pull':

                //一炮多响的情况下，点过等于点胡
                // if (this._actions[chairId].hu) {
                //     let canHuCount = (() => {
                //         let flag = false;
                //         for (const cid in this._actions) {
                //             if (cid != chairId && this._actions[cid] && this._actions[cid].hu) {
                //                 flag = true;
                //             }
                //         }
                //         return flag;
                //     })();
                //     let doHuCount = this._actionCache.hu.length;
                //     if (canHuCount || doHuCount) {
                //         return this.onMessage(chairId, "hu_pull");
                //     }
                //     //如果我可以胡却没有胡，在胡ban里加入
                //     else {
                //         this._huBan[chairId].push(this._lastCard);
                //     }
                // }

                this._actions[chairId] = null;
                for (var i in this._actionCache) {
                    var index = this._actionCache[i].indexOf(chairId);
                    if (index > -1) {
                        this._actionCache[i].splice(index, 1);
                    }
                }
                //this._actionCache = {
                //    peng : [],
                //    gang : [],
                //    hu : []
                //};
                for (var i in this._actions) {
                    if (!this._actions[i]) {
                        continue;
                    }
                    if (this._actions[i].peng ||
                        this._actions[i].gang ||
                        this._actions[i].hu ||
                        (this._actions[i].chi && this._actions[i].chi.length)) {
                        return;
                    }
                }
                this.doAction();
                // this._turn = this.searchTurn();
                // this.sync();
                break;


                // case 'pao_pull':
                //     if (this._pao.hasOwnProperty(chairId)) return;
                //     if (data.pao < 0) data.pao = 0;
                //     if (data.pao > 4) data.pao = 4;
                //     this._pao[chairId] = data.pao;
                //     if (Object.keys(this._pao).length == this._game.players.length) {
                //         //给所有用户发牌
                //         for (var j = 0; j < this._game.players.length; j++) {
                //             for (var i = 0; i < config.DEFAULT_HAND_CARDS; i++) {
                //                 this.mopai(j, false, false);
                //             }
                //             //this.updateTing(j);
                //         }

                //         this._turn = this._zhuang;
                //         this.pushPao();

                //         this.pushHolds();
                //         this.pushGameInfo();
                //         this.record("holds_push", JSON.parse(JSON.stringify(this._handCards)));
                //         this.pushTurn();
                //         this.record("turn_push", { turn: this._turn });

                //         this.mopai(this._turn, true, true);
                //     }
                //     else {
                //         this._turn = -1;
                //         this.pushPao();
                //     }
                //     //this.sync();
                //     break;

        }

    }



    end() {
        //this.sync();
    }


    /**
     * 摸牌
     * @param chairId
     */
    mopai(chairId, checkAnGang = false, isSend = false) {
        if(this._cards.length <= 16){
            return this.sendXiaojie([]);
        }
        // if (!this._cards.length) {
            // return this.sendXiaojie([]);
        // }
        this._mopai = chairId;

        var card = this._cards.pop();
        //如果是花牌
        if (card >= 34) {
            this._hua[chairId].push(card);
            this.sendToRoom("hua_mopai_push", {
                chairId: chairId,
                card: card
            });
            //     // this.record("hua_mopai_push", {
            //     //     chairId: chairId,
            //     //     card: card
            //     // }); 
            return this.mopai(chairId, checkAnGang, isSend);
        }

        this._handCards[chairId].push(card);
        this._handCardsMap[chairId][card]++;
        this._actions = {};
        this._zimoCard = -1;

        if (!checkAnGang) return;
        var action = {
            peng: 0,
            gang: 0,
            hu: 0
        }
        var gangCard = this.checkAnGang(chairId);
        if (gangCard === false) {
            gangCard = this.checkPengGang(chairId);
        }
        if (gangCard !== false) {
            action.gang = 1;
            this._actions[chairId] = action;
        }

        if (isSend) {
            this.sendToRoom("mopai_push", {
                chairId: chairId,
                card: card
            });

            this.record("mopai_push", {
                chairId: chairId,
                card: card
            });
        }

        //hu
        if (this.checkHu(chairId, card)) {
            action.hu = 1;
            this._actions[chairId] = action;
            this._zimoCard = card;
        }
        if (Object.keys(this._actions).length) {
            this._turn = -1;
            this.pushTurn();
            this.record("turn_push", {
                turn: this._turn
            });
        }
        this.pushActions();
    }

    sendXiaojie(cids) {
        super.end();

        var changed = [0, 0, 0, 0];
        let calScore = (chairId, zimo, huCard) => {
            let cp = Object.assign({}, this._handCardsMap[chairId]);
            if (!zimo) {
                cp[huCard]++;
            }
            let chong = {
                info: [],
                value: 1
            }
            //红中、发财、自风位刻子一冲
            this._combo[chairId].forEach(combo => {
                if (['angang', 'penggang', 'gang', 'peng'].includes(combo.type)) {
                    if (combo.card == 31) {
                        chong.info.push("红中刻子1冲");
                        chong.value += 1;
                    } else if (combo.card == 32) {
                        chong.info.push("发财刻子1冲");
                        chong.value += 1;
                    } else if (combo.card == this._pos[chairId]) {
                        chong.info.push("自风位刻子1冲");
                        chong.value += 1;
                    }
                    else if(combo.card == 33){
                        chong.info.push("白板刻子1冲");
                        chong.value++;
                    }
                }
            });
            if (cp[31] >= 3) {
                chong.info.push("红中刻子1冲");
                chong.value += 1;
            }
            if (cp[32] >= 3) {
                chong.info.push("发财刻子1冲");
                chong.value += 1;
            }
            if (cp[this._pos[chairId]] >= 3) {
                chong.info.push("自风位刻子1冲");
                chong.value += 1;
            }
            if(!this._roomInfo.gameConfig.hongzhong && cp[33] >= 3){
                chong.info.push("白板刻子1冲");
                chong.value++;
            }

            //混一色4冲
            let se = [0, 0, 0, 0];
            for (let item in cp) {
                item = Number(item);
                if(!cp[item || cp[item] == this._magic]){
                    continue;
                }

                if (item >= 27) {
                    se[3] = 1;
                } else {
                    se[Math.floor(item / 9)] = 1;
                }
            }

            this._combo[chairId].forEach(item => {
                if (item.card >= 27) {
                    se[3] = 1;
                } else {
                    se[Math.floor(item.card / 9)] = 1;
                }
            })
            if (se.filter(item => item == 1).length == 2 && se[3] == 1) {
                chong.info.push("混一色4冲");
                chong.value += 4;
            }

            //清一色、3个财神或4个财神8冲
            if (se.filter(item => item == 1).length == 1) {
                chong.info.push("清一色8冲");
                chong.value += 8;
            }
            if (cp[this._magic] == 3) {
                chong.info.push("3个财神8冲");
                chong.value += 8;
            }
            if (cp[this._magic] == 4) {
                chong.info.push("4个财神8冲");
                chong.value += 8;
            }

            //1个花1冲
            // this._hua[chairId].forEach(item => {
            //     item -= 34;
            //     chong.info.push("春夏秋冬梅兰竹菊".split('')[item] + '1冲');
            //     chong.value += 1;
            // });

            //春夏秋冬、梅兰竹菊加任意一个1冲的 = 8冲
            if (
                //至少5个花
                (
                    this._hua[chairId].length > 4 &&
                    (
                        this._hua[chairId].filter(item => item <= 37).length >= 4 ||
                        this._hua[chairId].filter(item => item >= 38).length >= 4
                    )
                ) ||
                (
                    //至少4个花
                    this._hua[chairId].length >= 4 &&
                    (
                        this._hua[chairId].filter(item => item <= 37).length >= 4 ||
                        this._hua[chairId].filter(item => item >= 38).length >= 4
                    ) &&
                    chong.info.find(item => item.indexOf("刻子"))
                )
            ) {
                chong.info.push("超级8冲");
                chong.value += 8;
            }

            //自风位花1冲
            let pos = this._pos[chairId] - 27;
            if (
                this._hua[chairId].includes(34 + pos)
            ) {
                chong.info.push("自风位花1冲")
                chong.value += 1;
            }
            if (this._hua[chairId].includes(38 + pos)) {
                chong.info.push("自风位花1冲")
                chong.value += 1;
            }

            //混一色+任意刻子+任意自风花 = 8冲
            if(chong.info.includes("混一色") && chong.info.includes("1冲") ){
                chong.value += 8;
            }

            //8冲封顶
            if (chong.value > 4) {
                chong.value = 4;
            }

            return chong;
        }

        let score = 0;
        let niaoCards = [];
        do {

            let niao = Number(this._roomInfo.gameConfig.zhaniao);
            if (niao !== niao) {
                break;
            }
            // let niaocards = [];
            if (niao > 0 && chairId != -1) {
                for (let i = 0; i < niao && i < this._cards.length; i++) {
                    let niaoCard = this._cards.pop();
                    niaoCards.push(niaoCard);
                    let mod = niaoCard % 9 + 1;
                    let score;
                    if (
                        niaoCard >= 27
                        // || (niaoCard < 27 && mod == 1)
                    ) {
                        score += 10;
                    } else if (mod == 1) {
                        score += 10;
                    } else if (mod >= 6 && mod <= 9) {
                        score += mod;
                    } else {
                        score += 5;
                    }
                }
            }
        } while (0);

        //多个人胡的情况，点炮的当庄
        //多人胡的情况不可能出现自摸
        let chongs = [];

        if (cids.length > 1) {
            this._lastWinner = this._lastChair;

            cids.forEach(chairId => {
                let chong = calScore(chairId, false, this._lastCard);
                chongs[chairId] = chong;
                //点炮的人扣掉
                let val = Math.pow(2, chong.value - 1);
                changed[this._lastChair] -= val;
                changed[chairId] += val;
                //扎鸟
                changed[this._lastChair] -= score;
                changed[chairId] += score;
            });
        }
        //只有一个人胡的情况
        else if (cids.length == 1) {
            this._lastWinner = cids[0];
            let zimo = this.isHisTurn(cids[0]);
            let chong = calScore(cids[0], zimo, this._lastCard);
            chongs[cids[0]] = chong;
            if (zimo) {

                //我吃别人的
                let cpgCount = {};
                this._combo[cids[0]].forEach(item => {
                    if (item.type != 'angang') {
                        cpgCount[item.from] = cpgCount[item.from] || 0;
                        cpgCount[item.from]++;
                    }
                });

                //别人吃我的
                let myCpgCount = {};
                // this._combo.forEach((combo,cid) => {
                for (const [cid, combo] of Object.entries(this._combo)) {
                    combo.forEach(item => {
                        if (item.type != 'angang') {
                            if (item.from == cids[0]) {
                                myCpgCount[cid] = myCpgCount[cid] || 0;
                                myCpgCount[cid]++;
                            }
                        }
                    });
                };

                //三摊只有自摸生效
                this._game.players.forEach((u, c) => {
                    if (c == cids[0]) return;
                    let val = Math.pow(2, chong.value - 1) + score;
                    if (this._roomInfo.gameConfig.santan) {
                        if (cpgCount[c] >= 3 || myCpgCount[c] >= 3) {
                            val *= 3;
                        }
                    }
                    changed[c] -= val;
                    changed[cids[0]] += val;
                });
            } else {
                let val = Math.pow(2, chong.value - 1);
                changed[this._lastChair] -= (val + score);
                changed[cids[0]] += (val + score);
            }
        }
        //没人胡的情况
        else {

        }



        this.changeScore(changed);

        //记录上一局的分
        if (this._gameCount > 1) {
            this._eachTurnScore[this._gameCount - 1] = this._eachTurnScore[this._gameCount - 1] || [];

            for (let i = 0; i < changed.length; i++) {
                this._eachTurnScore[this._gameCount - 1].push(this._gameScore[i] - this._lastGameScore[i]);
            }
        } else {
            this._eachTurnScore[0] = JSON.parse(JSON.stringify(this._gameScore));
        }

        this._lastGameScore = JSON.parse(JSON.stringify(this._gameScore));


        var data = {
            huCard: this._lastCard,
            huMan: cids,
            gameScore: this._gameScore,
            gameCount: this._gameCount,
            zhuang: this._zhuang,
            roomInfo: this._roomInfo,
            scoreChanged: changed,
            handCards: self._handCards,
            combo: self._combo,
            dianpao: (() => {
                if (cids.length >= 2) {
                    return this._lastChair;
                } else if (cids.length == 1) {
                    return this.isHisTurn(cids[0]) ? -1 : this._lastChair
                }
                return -1;
            }),
            // pao: self._pao,
            tongji: self._xjtongji,
            niaoCards,
            chongs,
            hua: this._hua
        }

        this._state = 'free';
        for (var i = 0; i < this._ready.length; i++) {
            this._ready[i] = 'free';
        }

        this.record("record_end_push");

        //var all_cards = [];
        //for(var i=0;i<this._game.players.length;i++){
        //    all_cards[i] = this._handCards[i];
        //}
        //all_cards[chairId].push(card);
        this.sendToRoom("all_cards_push", {
            handCards: this._handCards,
            huMan: cids,
            huCard: this._lastCard
        });
        this.sendToRoom("xiaojie_push", data);
        if (this._gameCount == this._roomInfo.gameConfig.playcount) {
            this.sendToRoom("zongjie_push", {
                gameScore: this._gameScore,
                tongji: this._tongji,
                allScoreInfo: this._eachTurnScore
            });

            //this._record =
            this.forceDismissRoom();
        }

        // this.sync();
    }

    doAction() {
        var lastCard = this._lastCard;
        //if(lastCard == -1) return;
        this._userActions = {};
        this._actions = {};
        var self = this;

        this._lastChiMan = -1;
        this._lastChiBan = [];

        if (this._actionCache.hu.length) {

            //允许一炮多响


            // //应用截胡！
            // var chairId = this._actionCache.hu[0];

            // for (var i = 1; i < 4; i++) {
            //     var real = (this._lastChair + i) % this._userInfo.length;
            //     if (this._actionCache.hu.indexOf(real) > -1) {
            //         chairId = real;
            //         break;
            //     }
            // }
            // //zimo

            // this._userActions[chairId] = 'hu';
            // // this._showAllCards = 1;
            // this._turn = -1;
            // //胡牌计算分数
            // var fan = 0,
            //     paixings = null,
            //     zimo = false;

            // var huCard = -1;

            // if (this.isHisTurn(chairId)) {
            //     //hu = this._tingMap[chairId][this._zimoCard];
            //     huCard = this._zimoCard;
            //     paixings = this.checkHu(chairId, huCard);
            //     zimo = true;
            // } else {
            //     //hu = this._tingMap[chairId][this._lastCard];
            //     huCard = this._lastCard;
            //     paixings = this.checkHu(chairId, huCard, true);
            // }
            // if (paixings && paixings.type == '7dui' && this._roomInfo.gameConfig.qiduifan == 1) {
            //     fan++;
            // }
            // if (paixings && paixings.type != '7dui') {
            //     if (this._roomInfo.gameConfig.jiang258fan) {
            //         for (var i = 0; i < paixings.length; i++) {
            //             var iscontinue = true;
            //             for (var j = 0; j < paixings[i].length; j++) {
            //                 if (paixings[i][j].type == mjhu.MJType.jiang && constant.CARD_258.indexOf(paixings[i][j].value) > -1) {
            //                     fan++;
            //                     iscontinue = false;
            //                     break;
            //                 }
            //             }
            //             if (!iscontinue) break;
            //         }
            //     }
            //     if (this._roomInfo.gameConfig.hu258fan &&
            //         constant.CARD_258.indexOf(huCard) > -1) {
            //         fan++;
            //     }
            // }
            // //if(hu.type == '7dui' && this._roomInfo.gameConfig.qiduifan == 1){
            // //    fan++;
            // //}
            // //if(hu.type != '7dui'){
            // //    if(this._roomInfo.gameConfig.jiang258fan
            // //        && constant.CARD_258.indexOf(hu.jiang) > -1){
            // //        fan++;
            // //    }
            // //    if(this._roomInfo.gameConfig.hu258fan
            // //        && constant.CARD_258.indexOf(huCard) > -1){
            // //        fan++;
            // //    }
            // //}

            // var changed = [0, 0, 0, 0];
            // var selfPao = 0,
            //     otherPao = 0;
            // var others = 0;
            // this._game.players.forEach((player, index) => {
            //     if (index == chairId) return;
            //     var score =
            //         //炮子分
            //         (
            //             //普通平胡不变,只炸不胡炮子分*2
            //             constant.SCORE_BASE
            //             //自摸翻倍
            //             *
            //             (zimo ? 2 : 1) +
            //             constant.SCORE_BASE * (zimo ? 2 : 1) * Math.pow(2, fan)
            //             //庄家翻倍
            //             *
            //             (chairId == self._zhuang ? 2 : (index == self._zhuang ? 2 : 1))
            //         )
            //         //基础分
            //         //*(self._roomInfo.gameConfig.hu+1)
            //         //*
            //         //点炮其他人不扣分
            //         *
            //         (!zimo && index != self._lastChair ? 0 : 1)

            //     //吃碰杠三手付3倍
            //     if (this._roomInfo.gameConfig.santan) {
            //         let cpgCount = this._combo[index].filter(item => {
            //             return item.type != 'angang' && item.from == chairId
            //         }).length;
            //         if (cpgCount >= 3) {
            //             score *= 3;
            //         }
            //     }


            //     //var score = constant.SCORE_BASE * ((index == self._zhuang?2:1)*(zimo?2:1)
            //     //    +(zimo?(self._pao[index]+self._pao[chairId]):(index == self._lastChair?self._pao[self._lastChair]+self._pao[chairId]:0)))
            //     //    * Math.pow(2,fan);
            //     //var score = 0;
            //     //if(zimo){
            //     //    score = constant.SCORE_BASE * ((index == self._zhuang?2:1)*2+(self._pao[index]+self._pao[chairId]))*Math.pow(2,fan);
            //     //}
            //     //else{
            //     //    if(self._lastChair == index){
            //     //        score = constant.SCORE_BASE * ((index == self._zhuang?2:1)+(self._pao[self._lastChair]+self._pao[chairId]))*Math.pow(2,fan);
            //     //    }
            //     //}

            //     changed[chairId] += score;
            //     changed[index] -= score;
            // });
            // this.changeScore(changed);

            // if (zimo) this._tongji[chairId].zimo++;
            // else {
            //     this._tongji[chairId].jiepao++;
            //     this._tongji[this._lastChair].dianpao++;
            // }
            this._turn = -1;
            this.pushTurn();
            this.record("turn_push", {
                turn: this._turn
            });

            this._actionCache.hu.forEach(cid => {
                this.sendToRoom("action_result_push", {
                    chairId: cid,
                    action: "hu",
                    card: huCard
                });
                this.record("action_result_push", {
                    chairId: cid,
                    action: "hu",
                    card: huCard
                });
            });



            //this.sync();


            this.sendXiaojie(this._actionCache.hu);

            // for(var i = 0; i < this._actionCache.hu.length; i++){
            //     var chairId = this._actionCache.hu[i];
            //     this._userActions[chairId] = constant.ACTION_HU;
            // }
            // this.end();
        } else if (this._actionCache.gang.length) {
            // for(var i = 0; i < this._actionCache.gang.length; i++) {
            var i = this._actionCache.gang[0];
            //如果是我的回合，必然是暗杠或者碰杠
            if (this.isHisTurn(i)) {
                var angang = this.checkAnGang(i);
                var penggang = this.checkPengGang(i);
                if (angang !== false) {
                    //增加组合
                    this._combo[i].push({
                        type: "angang",
                        card: angang
                    });
                    //删除手牌
                    this.removeHandCard(i, angang, 4);

                    //赢家收取其他玩家两倍底分
                    // var changed = [0, 0, 0, 0];
                    // this._game.players.forEach(function (player, index) {
                    //     if (i == index) return;
                    //     changed[i] += constant.SCORE_BASE * 2;
                    //     changed[index] -= constant.SCORE_BASE * 2;
                    // });
                    // this.changeScore(changed);

                    this._tongji[i].angang++;
                    this._xjtongji[i].angang++;

                    this.sendToRoom("action_result_push", {
                        chairId: i,
                        action: "angang",
                        card: angang
                    });
                    this.record("action_result_push", {
                        chairId: i,
                        action: "angang",
                        card: angang
                    });

                } else if (penggang !== false) {
                    for (var j = 0; j < this._combo[i].length; j++) {
                        var combo = this._combo[i][j];
                        if (combo.type == 'peng' && combo.card == penggang) {
                            combo.type = 'gang';
                            this.removeHandCard(i, penggang, 1);
                            //收取其他玩家一倍底分
                            var changed = [0, 0, 0, 0];
                            this._game.players.forEach(function (player, index) {
                                if (i == index) return;
                                changed[i] += constant.SCORE_BASE;
                                changed[index] -= constant.SCORE_BASE;
                            });
                            this.changeScore(changed);

                            this._tongji[i].minggang++;
                            this._xjtongji[i].minggang++;

                            this.sendToRoom("action_result_push", {
                                chairId: i,
                                action: "penggang",
                                card: penggang,
                            });
                            this.record("action_result_push", {
                                chairId: i,
                                action: "penggang",
                                card: penggang
                            });

                            break;
                        }
                    }
                }

            }
            //点杠
            else {
                var card = this.checkDianGang(i, this._lastCard);
                //增加组合
                this._combo[i].push({
                    type: "gang",
                    card: lastCard,
                    from: this._lastChair
                });
                //删除手牌
                this.removeHandCard(i, lastCard, 3);
                //删除打过的牌
                var index = this._outCards[this._lastChair].lastIndexOf(lastCard);
                if (index > -1) {
                    this._outCards[this._lastChair].splice(index, 1);
                }
                //收取点杠者一倍底分
                var changed = [0, 0, 0, 0];
                changed[this._lastChair] -= constant.SCORE_BASE;
                changed[i] += constant.SCORE_BASE;

                this.changeScore(changed);

                this._tongji[this._lastChair].diangang++;
                this._tongji[i].minggang++;
                this._xjtongji[this._lastChair].diangang++;
                this._xjtongji[i].minggang++;

                this.sendToRoom("action_result_push", {
                    chairId: i,
                    action: "diangang",
                    card: lastCard,
                    from: this._lastChair
                });
                this.record("action_result_push", {
                    chairId: i,
                    action: "diangang",
                    card: lastCard,
                    from: this._lastChair
                });
            }
            this._userActions[i] = 'gang';
            this._turn = i;
            this.pushTurn();
            this.record("turn_push", {
                turn: this._turn
            });

            //this.updateTing(i);

            this.mopai(i, true, true);
            //this.sync();

        } else if (this._actionCache.peng.length) {
            //因为涉及到出牌，所以先碰的人生效（事实上不会出现两个同时碰的情况)
            var chairId = this._actionCache.peng[0];
            this._userActions[chairId] = 'peng';
            //删除手牌
            this.removeHandCard(chairId, lastCard, 2);

            //删除上一个出牌
            this._outCards[this._lastChair].pop();
            //增加组合
            this._combo[chairId].push({
                type: 'peng',
                card: lastCard,
                from: this._lastChair
            });
            this._turn = chairId;

            this.pushTurn();
            this.record("turn_push", {
                turn: this._turn
            });

            this.sendToRoom("action_result_push", {
                chairId: chairId,
                action: "peng",
                card: lastCard,
                from: this._lastChair
            });
            this.record("action_result_push", {
                chairId: chairId,
                action: "peng",
                card: lastCard,
                from: this._lastChair
            });

            if (this.checkPengGang(chairId) !== false || this.checkAnGang(chairId) !== false) {
                this._actions[chairId] = {
                    peng: 0,
                    gang: 1,
                    hu: 0,
                }
                this.pushActions();
            }

            //this.sync();
        } else if (this._actionCache.chi && this._actionCache.chi.length) {
            let [cid, cards] = this._actionCache.chi[0];

            //吃牌不能打头尾
            this._lastChiMan = this._lastChair;
            cards = cards.sort((a, b) => a - b);
            // this._lastChiBan = [Number(lastCard)];
            //吃中
            if (cards[1] - cards[0] == 2) {
                this._lastChiBan = [Number(lastCard)];
            }
            // 吃头
            else if (cards[0] - lastCard == 1) {
                this._lastChiBan = [Number(lastCard)]//, Number(cards[1])];
                if(lastCard % 9 + 1 <= 6){
                    this._lastChiBan.push(Number(lastCard) + 3);
                }
            }
            // 吃尾
            else if (lastCard - cards[1] == 1) {
                this._lastChiBan = [Number(lastCard)]//, Number(cards[0])];
                if(lastCard % 9 + 1 >= 4){
                    this._lastChiBan.push(Number(lastCard) - 3);
                }
            }

            for (let card of cards) {
                this.removeHandCard(cid, card, 1);
            }
            this._outCards[this._lastChair].pop();
            let combo = {
                type: 'chi',
                value: lastCard,
                source: [cards[0], cards[1], lastCard].sort(function (a, b) {
                    return a - b;
                }),
                from: this._lastChair,
                card: lastCard
            }
            this._combo[cid].push(combo)
            this._turn = cid;
            this.pushTurn();
            this.sendToRoom("action_result_push", {
                chairId: cid,
                action: "chi",
                card: lastCard,
                cost: cards,
                from: this._lastChair
            });
            this.record("action_result_push", {
                chairId: cid,
                action: "chi",
                card: lastCard,
                cost: cards,
                from: this._lastChair
            });

            if (this.checkPengGang(cid) !== false || this.checkAnGang(cid) !== false) {
                this._actions[cid] = {
                    peng: 0,
                    gang: 1,
                    hu: 0,
                }
                this.pushActions();
            }
        }

        //guo
        else {
            this._turn = this.searchTurn();
            if (this._turn == -1) {
                this._turn = this._lastChair;
                this.moveToNextPlayer();
            }
            if (this._handCards[this._turn].length % 3 != 2) {
                this.mopai(this._turn, true, true);
            } else {
                this.pushTurn();
            }
            //this.sync();
        }

    }


    /**
     *  洗牌
     */
    xipai() {
        //0-8 wan
        for (let j = 0; j < 9; j++) {
            for (let i = 0; i < 4; i++) {
                this._cards.push(j);
            }
        }
        //9-17 tong
        for (let i = 9; i < 18; i++) {
            for (let j = 0; j < 4; j++) {
                this._cards.push(i);
            }
        }
        //18-26 tiao
        for (let i = 18; i < 27; i++) {
            for (let j = 0; j < 4; j++) {
                this._cards.push(i);
            }
        }

        //是否包含风牌
        // if (this._roomInfo.gameConfig.feng) {
        for (let i = 27; i < 34; i++) {
            for (let j = 0; j < 4; j++) {
                this._cards.push(i);
            }
        }
        // }

        //追加花牌
        //34 - 41
        for (let i = 0; i < 8; i++) {
            this._cards.push(i + 34);
        }


        //xipai
        for (var i = 0, len = this._cards.length; i < len; i++) {
            var rand1 = utils.rand(0, len - 1);
            var rand2 = utils.rand(0, len - 1);
            var temp = this._cards[rand1];
            this._cards[rand1] = this._cards[rand2];
            this._cards[rand2] = temp;
            //this._cards[rand1] ^= this._cards[rand2];
            //this._cards[rand2] ^= this._cards[rand1];
            //this._cards[rand1] ^= this._cards[rand2];
        }

    }


    moveToNextPlayer() {
        this._turn++;
        this._turn %= this._game.players.length;

        this.pushTurn();
        this.record("turn_push", {
            turn: this._turn
        });

    }

    checkPeng(chairId, card) {
        return this._handCardsMap[chairId][card] > 1;
    }

    // checkChi(chairId, card) {

    // }

    checkAnGang(chairId) {
        for (var i = 0; i < 34; i++) {
            if (this._handCardsMap[chairId][i] > 3) {
                return parseInt(i);
            }
        }
        return false;
    }

    checkDianGang(chairId, card) {
        return this._handCardsMap[chairId][card] > 2;
    }

    checkPengGang(chairId) {
        for (var i = 0; i < this._combo[chairId].length; i++) {
            var combo = this._combo[chairId][i];
            if (combo.type == 'peng') {
                if (this._handCardsMap[chairId][combo.card] > 0) {
                    return combo.card;
                }
            }
        }
        return false;
    }

    checkGang(chairId, card, undefined) {
        if (card === undefined) {
            //暗杠
            for (var i = 0; i < 34; i++) {
                if (this._handCardsMap[chairId][i] > 3 && i != this._magic) {
                    return true;
                }
            }
            //点杠
            if (this._lastCard > -1) {
                if (this._handCardsMap[chairId][i] > 2 && i != this._magic) {
                    return true;
                }
            }
            return false;
        }
        //碰杠
        for (var i = 0; i < this._combo[chairId].length; i++) {
            if (this._combo[chairId][i].type == 'peng' &&
                this._combo[chairId][i].card == card
            ) {
                return true;
            }
        }
        return this._handCardsMap[chairId][card] > 2;
    }

    checkHu(chairId, card, add = false) {
        var flag = true;

        //过胡的情况，禁止胡
        if (this._huBan[chairId].includes(card)) {
            return false;
        }

        //只能自摸胡
        if (this._roomInfo.gameConfig.hu > 0 && !this.isHisTurn(chairId)) {
            //flag = this.isHisTurn(chairId);
            return false;
        }

        var magic = this._magic;


        //4个直接胡
        if (this._handCardsMap[chairId][magic] >= 4) {
            return true;
        }
        //3个以上必须自模胡
        //持有魔术牌的时候只能自摸胡
        if (this._handCardsMap[chairId][magic] >= 3) {
            if (!this.isHisTurn(chairId)) {
                return false;
            }
        }
        //1-2个看情况自模胡
        if (this._handCardsMap[chairId][magic] <= 2 && this._handCardsMap[chairId][magic] > 0) {
            //强制自摸的情况
            if (this._roomInfo.gameConfig.forceZimo && !this.isHisTurn(chairId)) {
                return false;
            }
        }

        var holds = Object.assign([], this._handCards[chairId]);
        var map = Object.assign({}, this._handCardsMap[chairId]);
        if (add) {
            holds.push(card);
            map[card]++;
        }


        //7dui
        if (this._roomInfo.gameConfig.qiduifan > 0) {
            if (holds.length == 14) {
                var duizi = 0;
                for (var i in map) {
                    if (i == magic) continue;

                    if (map[i] == 2) {
                        duizi++;
                    }
                }
                var left = 14 - duizi * 2;
                if (left <= 2 * map[magic]) {
                    return {
                        type: '7dui'
                    };
                }
            }
        }


        var ret = mjhu.calPaiXing(holds, map, magic);
        // console.log(JSON.stringify(ret));
        if (ret && ret.length) {
            let flag = true;

            //单吊财神的情况，只允许自模胡
            ret = ret.filter(combos => {
                let jiang = combos.find(item => item.type == mjhu.MJType.jiang);
                if(!jiang){
                    return false;
                }
                //财神中有将
                //单吊万能牌
                if(jiang.source.includes(magic) && jiang.source.includes(card)){
                    //如果不是自摸
                    if(!this.isHisTurn(chairId)){
                        flag = false;
                        return false;
                    }
                }
                return true;
            });
            if(!flag){
                return false;
            }
            if(!ret.length){
                return false;
            }

            // if (this._roomInfo.gameConfig.jiang258) {
            //     var canhu = false;
            //     for (var i = 0; i < ret.length; i++) {
            //         for (var j = 0; j < ret[i].length; j++) {
            //             if (ret[i][j].type == mjhu.MJType.jiang && constant.CARD_258.indexOf(ret[i][j].value) > -1) {
            //                 canhu = true;
            //             }
            //         }
            //     }
            //     if (!canhu) {
            //         return false;
            //     }
            // }
            return ret;
        }
        return false;

    }


    

    /**
     * 查找该出牌的人
     */
    searchTurn() {
        for (var i = 0; i < this._handCards.length; i++) {
            if (this._handCards[i].length % 3 == 2) {
                return i;
            }
        }
        return -1;
    }

    isHisTurn(chairId) {
        return this._handCards[chairId].length % 3 == 2;
    }

    isZhuang(chairId) {
        return chairId == this._zhuang;
    }

    removeHandCard(chairId, card, times = 1) {
        for (var i = 0; i < times; i++) {
            var index = this._handCards[chairId].indexOf(card);
            if (index == -1) break;

            this._handCards[chairId].splice(index, 1);
            this._handCardsMap[chairId][card]--;
        }

    }


    /**
     * 检测是否可以吃
     * @param {*} holds 
     * @param {*} card 
     */
    checkChi(chairId, card) {
        if (card > 26) return null;
        var map = this._handCardsMap[chairId];

        var ret = [];
        var mod = card % 9;

        //chiwei
        if (mod > 1) {
            if (map[card - 1] && map[card - 2]) {
                ret.push([card - 1, card - 2]);
            }
        }
        //chizhong
        if (mod > 0 && mod < 8) {
            if (map[card - 1] && map[card + 1]) {
                ret.push([card - 1, card + 1]);
            }
        }
        //chitou
        if (mod < 7) {
            if (map[card + 1] && map[card + 2]) {
                ret.push([card + 1, card + 2]);
            }
        }
        return ret.length ? ret : null;
    }


    getNextPlayer(chairId = -1) {
        var turn;
        if (chairId == -1) {
            turn = this._turn + 1;
        } else {
            turn = chairId + 1;
        }
        return turn %= this._game.players.length;
    }

}

module.exports = HENMJGame;